package com.softeem.score.manager.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;
import com.softeem.score.manager.service.StudentService;
import com.softeem.score.model.entity.school.Student;
import com.softeem.score.model.vo.execlVo.StudentExcelVo;
import lombok.extern.slf4j.Slf4j;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;

@Slf4j
public class ExcelListener<T> implements ReadListener<T> {

    /**
     * 每隔5条存储数据库，实际使用中可以100条，然后清理list ，方便内存回收
     */
    private static final int BATCH_COUNT = 10;
    private final Long classesId;
    /**
     * 缓存的数据
     */
    private List<T> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

    //获取mapper对象
    private final StudentService studentService;

    // 构造方法接收 StudentMapper 和 classesId 参数
    public ExcelListener(StudentService studentService, Long classesId) {
        this.studentService = studentService;
        this.classesId = classesId;
    }

    // 每解析一行数据就会调用一次该方法
    @Override
    public void invoke(T data, AnalysisContext context) {
        // 把每行数据对象date存放到list中
        cachedDataList.add(data);
        // 达到BATCH_COUNT了，需要去存储一次数据库，防止数据几万条数据在内存，容易OOM
        if (cachedDataList.size() >= BATCH_COUNT) {
            saveData();
            // 存储完成清理 list
            cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        // excel解析完毕以后需要执行的代码
        // 这里也要保存数据，确保最后遗留的数据也存储到数据库
        saveData();
    }

    // 报存的方法
    private void saveData() {
        List<StudentExcelVo> studentExcelVos = (List<StudentExcelVo>) cachedDataList;
        studentExcelVos.forEach(data -> {
            log.info("解析到一条记录: {}", data);
            Student student = new Student();
            student.setStudentNumber(data.getStudentNumber());
            student.setName(data.getName());
            student.setSex("男".equals(data.getSex()) ? Integer.valueOf(1) : "女".equals(data.getSex()) ? 0 : null);
            student.setIdCard(data.getIdCard());
            student.setBirthday(LocalDate.parse(data.getBirthDate(), DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            student.setClassesId(classesId);
            student.setContactInformation(data.getContactInformation());
            student.setAddress(data.getAddress());
            studentService.saveStudent(student);
        });
    }
}